#include "UserInterface.h"
#include <iostream>
#include <iomanip>
#include <limits>
#include <algorithm>
#include <ctime>
#include <sstream>
using namespace std;
// 用户界面类构造函数
UserInterface::UserInterface()
{
    bankingSystem = make_shared<BankingSystem>();
}

// 运行用户界面的主函数
void UserInterface::run()
{
    bool exit = false;

    while (!exit)
    {
        displayMainMenu();

        int choice;
        cout << "Please choose: ";
        cin >> choice;

        // 清除输入缓冲区
        cin.clear();
        cin.ignore(numeric_limits<streamsize>::max(), '\n');

        switch (choice)
        {
        case 1:
            handleRegisterCustomer();
            break;
        case 2:
            handleAccessCustomer();
            break;
        case 3:
            handleViewAllAccounts();
            break;
        case 4:
            handleTransactionReports();
            break;
        case 5:
            exit = true;
            cout << "Thank you for using the Banking System. Goodbye!" << endl;
            break;
        default:
            cout << "Invalid choice. Please try again." << endl;
            waitForEnter();
        }
    }
}

// 显示主菜单
void UserInterface::displayMainMenu()
{
    cout << "\n===== Banking System =====" << endl;
    cout << "1. Register new customer" << endl;
    cout << "2. Access customer accounts" << endl;
    cout << "3. Display all bank accounts" << endl;
    cout << "4. Transaction reports" << endl;
    cout << "5. Exit" << endl;
}

// 处理注册新客户
void UserInterface::handleRegisterCustomer()
{
    cout << "\n===== Register New Customer =====" << endl;

    string name;
    cout << "Enter customer name: ";
    getline(cin, name);

    // 检查客户是否已存在
    if (bankingSystem->findCustomer(name))
    {
        cout << "Error: A customer with this name already exists." << endl;
        waitForEnter();
        return;
    }

    // 注册新客户
    auto customer = bankingSystem->registerCustomer(name);

    cout << "Customer " << name << " successfully registered!" << endl;
    cout << "Two bank accounts have been created:" << endl;
    cout << "- Savings Account: " << customer->getSavingsAccount()->getAccountId() << endl;
    cout << "- Checking Account: " << customer->getCheckingAccount()->getAccountId() << endl;

    waitForEnter();
}

// 处理访问客户账户
void UserInterface::handleAccessCustomer()
{
    cout << "\n===== Access Customer Accounts =====" << endl;

    string name;
    cout << "Enter customer name: ";
    getline(cin, name);

    // 查找客户
    auto customer = bankingSystem->findCustomer(name);
    if (!customer)
    {
        cout << "Error: Customer not found." << endl;
        waitForEnter();
        return;
    }

    // 显示客户菜单
    displayCustomerMenu(customer);
}

// 显示客户菜单
void UserInterface::displayCustomerMenu(const shared_ptr<Customer> &customer)
{
    bool returnToMain = false;

    while (!returnToMain)
    {
        auto savingsAccount = customer->getSavingsAccount();
        auto checkingAccount = customer->getCheckingAccount();

        cout << "\n===== Customer: " << customer->getName() << " =====" << endl;
        cout << "This customer has the following accounts:" << endl
                  << endl;

        cout << "1. Savings Account: " << savingsAccount->getAccountId() << endl;
        cout << "   Balance: ¥" << fixed << setprecision(2) << savingsAccount->getBalance() << endl
                  << endl;

        cout << "2. Checking Account: " << checkingAccount->getAccountId() << endl;
        cout << "   Balance: ¥" << fixed << setprecision(2) << checkingAccount->getBalance() << endl
                  << endl;

        cout << "Options:" << endl;
        cout << "1. Access Savings Account" << endl;
        cout << "2. Access Checking Account" << endl;
        cout << "3. View all transactions for this customer" << endl;
        cout << "4. Generate customer report" << endl;
        cout << "5. Return to main menu" << endl
                  << endl;

        int choice;
        cout << "Please choose: ";
        cin >> choice;

        // 清除输入缓冲区
        cin.clear();
        cin.ignore(numeric_limits<streamsize>::max(), '\n');

        switch (choice)
        {
        case 1:
            displayAccountMenu(savingsAccount, customer);
            break;
        case 2:
            displayAccountMenu(checkingAccount, customer);
            break;
        case 3:
            handleViewCustomerTransactions(customer);
            break;
        case 4:
            handleGenerateCustomerReport(customer);
            break;
        case 5:
            returnToMain = true;
            break;
        default:
            cout << "Invalid choice. Please try again." << endl;
            waitForEnter();
        }
    }
}

// 显示账户菜单
void UserInterface::displayAccountMenu(const shared_ptr<Account> &account, const shared_ptr<Customer> &customer)
{
    bool returnToCustomer = false;

    while (!returnToCustomer)
    {
        cout << "\n===== Bank Account: " << account->getAccountId() << " (" << account->getAccountType() << ") =====" << endl;
        cout << "Account holder: " << account->getOwnerName() << endl;
        cout << "Balance: ¥" << fixed << setprecision(2) << account->getBalance() << endl
                  << endl;

        cout << "Options:" << endl;

        int optionCount = 1;
        bool canDeposit = account->canDeposit();
        bool canWithdraw = account->canWithdraw();

        // 只显示账户支持的存款/取款选项
        if (canDeposit)
        {
            cout << optionCount << ". Deposit" << endl;
            optionCount++;
        }

        if (canWithdraw)
        {
            cout << optionCount << ". Withdraw" << endl;
            optionCount++;
        }

        // 所有账户都可以转账
        cout << optionCount << ". Transfer" << endl;
        int transferOption = optionCount++;

        cout << optionCount << ". View transaction history" << endl;
        int historyOption = optionCount++;

        cout << optionCount << ". Generate bank account report" << endl;
        int reportOption = optionCount++;

        cout << optionCount << ". Return to customer page" << endl;
        int returnOption = optionCount;

        cout << endl;

        int choice;
        cout << "Please choose: ";
        cin >> choice;

        // 清除输入缓冲区
        cin.clear();
        cin.ignore(numeric_limits<streamsize>::max(), '\n');

        // 根据账户功能处理选项
        if (canDeposit && canWithdraw)
        {
            switch (choice)
            {
            case 1:
                handleDeposit(account);
                break;
            case 2:
                handleWithdraw(account);
                break;
            case 3:
                handleTransfer(account);
                break;
            case 4:
                handleViewAccountTransactions(account);
                break;
            case 5:
                handleGenerateAccountReport(account);
                break;
            case 6:
                returnToCustomer = true;
                break;
            default:
                cout << "Invalid choice. Please try again." << endl;
                waitForEnter();
            }
        }
        else if (canDeposit && !canWithdraw)
        {
            switch (choice)
            {
            case 1:
                handleDeposit(account);
                break;
            case 2:
                handleTransfer(account);
                break;
            case 3:
                handleViewAccountTransactions(account);
                break;
            case 4:
                handleGenerateAccountReport(account);
                break;
            case 5:
                returnToCustomer = true;
                break;
            default:
                cout << "Invalid choice. Please try again." << endl;
                waitForEnter();
            }
        }
        else if (!canDeposit && canWithdraw)
        {
            switch (choice)
            {
            case 1:
                handleWithdraw(account);
                break;
            case 2:
                handleTransfer(account);
                break;
            case 3:
                handleViewAccountTransactions(account);
                break;
            case 4:
                handleGenerateAccountReport(account);
                break;
            case 5:
                returnToCustomer = true;
                break;
            default:
                cout << "Invalid choice. Please try again." << endl;
                waitForEnter();
            }
        }
        else
        {
            // 既不能存款也不能取款的情况
            if (choice == transferOption)
            {
                handleTransfer(account);
            }
            else if (choice == historyOption)
            {
                handleViewAccountTransactions(account);
            }
            else if (choice == reportOption)
            {
                handleGenerateAccountReport(account);
            }
            else if (choice == returnOption)
            {
                returnToCustomer = true;
            }
            else
            {
                cout << "Invalid choice. Please try again." << endl;
                waitForEnter();
            }
        }
    }
}

// 处理存款操作
void UserInterface::handleDeposit(const shared_ptr<Account> &account)
{
    cout << "\n===== Deposit to Account: " << account->getAccountId() << " =====" << endl;
    cout << "Current Balance: ¥" << fixed << setprecision(2) << account->getBalance() << endl
              << endl;

    double amount;
    cout << "Enter amount to deposit: ";
    cin >> amount;

    // 清除输入缓冲区
    cin.clear();
    cin.ignore(numeric_limits<streamsize>::max(), '\n');

    string note;
    cout << "Add note (optional): ";
    getline(cin, note);

    if (bankingSystem->deposit(account->getAccountId(), amount, note))
    {
        cout << "\nDeposit successful!" << endl;
        cout << "New balance: ¥" << fixed << setprecision(2) << account->getBalance() << endl;

        auto transactions = account->getTransactions();
        if (!transactions.empty())
        {
            cout << "Transaction ID: " << transactions.back()->getTransactionId() << " has been recorded." << endl;
        }
    }

    waitForEnter();
}

// 处理取款操作
void UserInterface::handleWithdraw(const shared_ptr<Account> &account)
{
    cout << "\n===== Withdraw from Account: " << account->getAccountId() << " =====" << endl;
    cout << "Current Balance: ¥" << fixed << setprecision(2) << account->getBalance() << endl
              << endl;

    double amount;
    cout << "Enter amount to withdraw: ";
    cin >> amount;

    // 清除输入缓冲区
    cin.clear();
    cin.ignore(numeric_limits<streamsize>::max(), '\n');

    string note;
    cout << "Add note (optional): ";
    getline(cin, note);

    if (bankingSystem->withdraw(account->getAccountId(), amount, note))
    {
        cout << "\nWithdrawal successful!" << endl;
        cout << "New balance: ¥" << fixed << setprecision(2) << account->getBalance() << endl;

        auto transactions = account->getTransactions();
        if (!transactions.empty())
        {
            cout << "Transaction ID: " << transactions.back()->getTransactionId() << " has been recorded." << endl;
        }
    }

    waitForEnter();
}

// 处理转账操作
void UserInterface::handleTransfer(const shared_ptr<Account> &account)
{
    cout << "\n===== Transfer from Account: " << account->getAccountId() << " =====" << endl;
    cout << "Current Balance: ¥" << fixed << setprecision(2) << account->getBalance() << endl
              << endl;

    string destAccountId;
    cout << "Enter destination account ID: ";
    getline(cin, destAccountId);

    // 检查目标账户是否存在
    auto destAccount = bankingSystem->findAccount(destAccountId);
    if (!destAccount)
    {
        cout << "Error: Destination account not found." << endl;
        waitForEnter();
        return;
    }

    double amount;
    cout << "Enter amount to transfer: ";
    cin >> amount;

    // 清除输入缓冲区
    cin.clear();
    cin.ignore(numeric_limits<streamsize>::max(), '\n');

    string note;
    cout << "Add note (optional): ";
    getline(cin, note);

    if (bankingSystem->transfer(account->getAccountId(), destAccountId, amount, note))
    {
        cout << "\nTransfer successful!" << endl;
        cout << "New balance: ¥" << fixed << setprecision(2) << account->getBalance() << endl;

        auto transactions = account->getTransactions();
        if (!transactions.empty())
        {
            cout << "Transaction ID: " << transactions.back()->getTransactionId() << " has been recorded." << endl;
        }
    }

    waitForEnter();
}

// 查看账户交易历史
void UserInterface::handleViewAccountTransactions(const shared_ptr<Account> &account)
{
    cout << "\n===== Transaction History for Account: " << account->getAccountId() << " =====" << endl;

    const auto &transactions = account->getTransactions();

    if (transactions.empty())
    {
        cout << "No transactions found for this account." << endl;
    }
    else
    {
        // 按时间戳排序交易记录
        vector<shared_ptr<Transaction>> sortedTransactions = transactions;
        sort(sortedTransactions.begin(), sortedTransactions.end(),
                  [](const shared_ptr<Transaction> &a, const shared_ptr<Transaction> &b)
                  {
                      return a->getTimestamp() < b->getTimestamp();
                  });

        for (const auto &transaction : sortedTransactions)
        {
            cout << "---------------------------------------------" << endl;
            cout << transaction->toString() << endl;
        }
    }

    waitForEnter();
}

// 生成账户报告
void UserInterface::handleGenerateAccountReport(const shared_ptr<Account> &account)
{
    string filename = "transactions_" + account->getAccountId() + "_" + getCurrentDate() + ".txt";
    account->generateAccountReport(filename);
    waitForEnter();
}

// 查看客户所有交易历史
void UserInterface::handleViewCustomerTransactions(const shared_ptr<Customer> &customer)
{
    cout << "\n===== Transaction History for Customer: " << customer->getName() << " =====" << endl;

    const auto &transactions = customer->getAllTransactions();

    if (transactions.empty())
    {
        cout << "No transactions found for this customer." << endl;
    }
    else
    {
        for (const auto &transaction : transactions)
        {
            cout << "---------------------------------------------" << endl;
            cout << transaction->toString() << endl;
        }
    }

    waitForEnter();
}

// 生成客户报告
void UserInterface::handleGenerateCustomerReport(const shared_ptr<Customer> &customer)
{
    string filename = "transactions_" + customer->getName() + "_" + getCurrentDate() + ".txt";
    // 将文件名中的空格替换为下划线
    replace(filename.begin(), filename.end(), ' ', '_');

    customer->generateCustomerReport(filename);
    waitForEnter();
}

// 查看所有银行账户
void UserInterface::handleViewAllAccounts()
{
    cout << "\n===== All Bank Accounts =====" << endl
              << endl;

    vector<shared_ptr<Account>> savingsAccounts = bankingSystem->getSavingsAccounts();
    vector<shared_ptr<Account>> checkingAccounts = bankingSystem->getCheckingAccounts();

    // 按所有者名称排序账户
    auto sortByOwner = [](const shared_ptr<Account> &a, const shared_ptr<Account> &b)
    {
        return a->getOwnerName() < b->getOwnerName();
    };

    sort(savingsAccounts.begin(), savingsAccounts.end(), sortByOwner);
    sort(checkingAccounts.begin(), checkingAccounts.end(), sortByOwner);

    cout << "SAVINGS ACCOUNTS:" << endl;
    if (savingsAccounts.empty())
    {
        cout << "No savings accounts found." << endl;
    }
    else
    {
        int count = 1;
        for (const auto &account : savingsAccounts)
        {
            cout << count << ". ID: " << account->getAccountId() << "  |  Owner: "
                      << left << setw(12) << account->getOwnerName() << "  |  Balance: ¥"
                      << fixed << setprecision(2) << account->getBalance() << endl;
            count++;
        }
    }

    cout << endl
              << "CHECKING ACCOUNTS:" << endl;
    if (checkingAccounts.empty())
    {
        cout << "No checking accounts found." << endl;
    }
    else
    {
        int count = 1;
        for (const auto &account : checkingAccounts)
        {
            cout << count << ". ID: " << account->getAccountId() << "  |  Owner: "
                      << left << setw(12) << account->getOwnerName() << "  |  Balance: ¥"
                      << fixed << setprecision(2) << account->getBalance() << endl;
            count++;
        }
    }

    cout << endl;
    cout << "Total Accounts: " << bankingSystem->getTotalAccountCount() << endl;
    cout << "Total Customers: " << bankingSystem->getTotalCustomerCount() << endl;
    cout << "Total Balance: ¥" << fixed << setprecision(2) << bankingSystem->getTotalBalance() << endl;

    waitForEnter();
}

// 处理交易报告
void UserInterface::handleTransactionReports()
{
    cout << "\n===== Transaction Reports =====" << endl;

    string filename = "transactions_" + getCurrentDate() + ".txt";
    bankingSystem->generateTransactionReport(filename);

    waitForEnter();
}

// 等待用户按回车键继续
void UserInterface::waitForEnter() const
{
    cout << "\nPress Enter to continue...";
    cin.get();
}

// 获取当前日期字符串
string UserInterface::getCurrentDate() const
{
    time_t t = time(nullptr);
    tm *now = localtime(&t);

    ostringstream oss;
    oss << (now->tm_year + 1900) << "-"
        << setw(2) << setfill('0') << (now->tm_mon + 1) << "-"
        << setw(2) << setfill('0') << now->tm_mday;

    return oss.str();
}